<template>
  <CDialog
    :title="title"
    v-model:visible="dialogVisible"
    :loading="loading"
    :confirmText="confirmTitle"
    cancelText="关闭"
    @confirm="handleConfirm"
    @cancel="dialogVisible = false"
  >
    <el-form ref="formRef" :model="formState" :rules="rules" label-position="top">
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="运输物" prop="transferCategory">
            <el-radio-group
              v-model="formState.transferCategory"
              @change="handleChangeTransferCategory"
            >
              <el-radio :label="item.value" v-for="item in DataCategoryOptions" :key="item.value">{{
                item.label
              }}</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item
            label="零部件/材料"
            prop="transferNodeNo"
            v-if="
              formState.transferCategory === 'ITEM' || formState.transferCategory === 'MATERIAL'
            "
          >
            <!-- :suffix-icon="h(GIcon, { type: 'c-xian-xia' }, $attrs)" -->
            <el-tree-select
              :suffix-icon="CIconArrowBottom"
              class="material-select-tree-wrapper"
              ref="bomTreeRef"
              v-model="formState.transferNodeNo"
              :render-after-expand="false"
              :expand-on-click-node="false"
              filterable
              :props="treeSelectProps"
              :load="loadNode"
              lazy
            >
              <template #default="{ data: { nodeNo, nodeName, dosage, unit }, node: { disabled } }">
                <div
                  class="node-item g-flex-between-center"
                  @click="handleSelectTransferNodeName(nodeNo, nodeName)"
                  v-if="!disabled"
                >
                  <span>{{ nodeName }}</span>
                  <span class="material-weight-text" v-if="isWeightUnit(unit)"
                    >{{ dosage }}{{ unit }}</span
                  >
                </div>
                <div class="node-item g-flex-between-center" @click.stop v-else>
                  <span>{{ nodeName }}</span>
                  <span class="material-weight-text" v-if="isWeightUnit(unit)"
                    >{{ dosage }}{{ unit }}</span
                  >
                </div>
              </template>
            </el-tree-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="运输方式" prop="transferMethod">
            <CSelect v-model="formState.transferMethod" placeholder="请选择" clearable>
              <el-option
                v-for="unit in TransportMethodOptions"
                :key="unit.value"
                :label="unit.label"
                :value="unit.value"
              />
            </CSelect>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="燃料类型" prop="fuelType">
            <CSelect v-model="formState.fuelType" placeholder="请选择" clearable>
              <el-option
                v-for="unit in FuelTypeOptions"
                :key="unit.value"
                :label="unit.label"
                :value="unit.value"
              />
            </CSelect>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="运载率" prop="transferRate">
            <CSelect v-model="formState.transferRate" placeholder="请选择" clearable>
              <el-option
                v-for="unit in TransportRatioOptions"
                :key="unit.value"
                :label="unit.label"
                :value="unit.value"
              />
            </CSelect>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="运输距离" prop="distance">
            <CDosageAndUnit
              v-model:dosage="formState.distance"
              v-model:unit="formState.distanceUnit"
              :unit-option="TransferDistanceUnitOption"
              :can-negative="false"
              placeholder="请输入"
            ></CDosageAndUnit>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="货物重量" prop="weight">
            <CDosageAndUnit
              v-model:dosage="formState.weight"
              v-model:unit="formState.weightUnit"
              :unit-option="TransferWeightUnitOption"
              :can-negative="false"
              placeholder="请输入"
            ></CDosageAndUnit>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="用量">
            <CDosageAndUnit
              v-model:dosage="dosageComputed"
              v-model:unit="unitComputed"
              :digit="9"
              placeholder="运输距离 * 货物重量"
              disabled
            ></CDosageAndUnit>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="备注" prop="remark">
            <el-input
              type="textarea"
              v-model="formState.remark"
              placeholder="可填写运输线路、收发地等信息"
              clearable
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </CDialog>
</template>

<script lang="ts" setup name="FlowDialog">
import { CSelect } from '@/components/CSelect';
import { withDefaults, defineProps, defineEmits, computed, watch, reactive, ref, h } from 'vue';
import { CDialog } from '@/components/CDialog';
import CDosageAndUnit from '@/businessComponents/CDosageAndUnit/index.vue';
import { GIcon } from '@/components/GIcon/index';
import CIconArrowBottom from '@/components/CIconArrowBottom/index.vue';
import type Node from 'element-plus/es/components/tree/src/model/node';

import {
  getNodeInfo,
  addTransportStageFlow,
  editTransportStageFlow,
  getBomTreeInTransport,
  getNodeWeight
} from '@/apis/pcf/myModel/modelDetail';
import type { ProcessDataItem, GetNodeInfoResult } from '@/apis/pcf/myModel/model/modelDetailModel';
import { useMessage } from '@/hooks/useMessage';
import {
  TransportMethodOptions,
  FuelTypeOptions,
  TransportRatioOptions,
  DataCategoryEnum,
  DataCategoryOptions,
  TransportMethodEnum,
  FuelTypeEnum,
  TransportRatioMap,
  TransferDistanceUnitOption,
  TransferWeightUnitOption
} from '@/constants/enum';
import { FlowDialogOperationType } from './transport-dialog';
import { rules } from './rules';
import { limitStrLength, isWeightUnit, transitionUnitToKg } from '@/utils';
import Decimal from 'decimal.js';
import type { ModelDetailResult } from '@/apis/pcf/myModel/model/modelManage';
import { getListBomTree } from '@/apis/pcf/myModel/modelDetail';

interface FlowDialogProps {
  visible: boolean;
  /**
   * 工序编号
   */
  processNo: string;
  /**
   * 流/运输路线编号
   */
  nodeNo: string;
  /**
   * 模型编号
   */
  modelNo: string;
  /**
   * 模型详情
   */
  modelDetail?: ModelDetailResult;
  flowItem?: ProcessDataItem;
}
const props = withDefaults(defineProps<FlowDialogProps>(), {});
const emits = defineEmits(['update:visible', 'refresh']);
const { createMessage } = useMessage();
const dialogVisible = computed({
  get: () => {
    return props.visible;
  },
  set: (value: boolean) => {
    emits('update:visible', value);
  }
});
watch(
  () => dialogVisible.value,
  val => {
    if (val) {
      init();
    }
  }
);

const formRef = ref();
const loading = ref(false);
const dirtyFlag = ref(false);
/**
 * 表单内容
 */
const formState = reactive({
  processNo: '',
  nodeNo: '',
  transferCategory: 'MAIN' as keyof typeof DataCategoryEnum,
  transferNodeName: '主产品',
  transferNodeNo: '',
  transferMethod: '' as unknown as keyof typeof TransportMethodEnum,
  fuelType: '' as unknown as keyof typeof FuelTypeEnum,
  transferRate: '' as unknown as keyof typeof TransportRatioMap,
  distance: '',
  distanceUnit: 'km',
  weight: '',
  weightUnit: 't',
  dosage: '',
  unit: 't·km',
  remark: ''
});
const sourceTransferNodeNo = ref('');
const sourceTransferNodeName = ref('');
const hasTransferNode = ref(false);
/**
 * 操作类型
 */
const operationType = ref<FlowDialogOperationType>();

/**
 * 弹窗标题
 */
const title = computed(() => {
  return operationType.value === 'ADD' ? '新增运输路线' : '编辑运输路线';
});

const confirmTitle = computed(() => {
  return operationType.value === 'ADD' ? '新增' : '保存';
});

/**
 * 初始化
 */
function init() {
  loading.value = false;
  formState.processNo = props.processNo;
  sourceTransferNodeNo.value = '';
  sourceTransferNodeName.value = '';
  if (!props.nodeNo) {
    operationType.value = 'ADD';
    formState.nodeNo = '';
    formState.transferCategory = 'MAIN' as unknown as keyof typeof DataCategoryEnum;
    formState.transferNodeName = '主产品';
    formState.transferNodeNo = '';
    formState.transferMethod = '' as unknown as keyof typeof TransportMethodEnum;
    formState.fuelType = '' as unknown as keyof typeof FuelTypeEnum;
    formState.transferRate = '' as unknown as keyof typeof TransportRatioMap;
    formState.dosage = '';
    formState.unit = 't·km';
    formState.distance = '';
    formState.distanceUnit = 'km';
    formState.remark = '';

    const { weight, weightUnit } = transitionUnitToKg(
      props.modelDetail?.weight || '',
      props.modelDetail?.weightUnit || 't'
    );
    formState.weight = String(weight);
    formState.weightUnit = weightUnit;
    dirtyFlag.value = false;
  } else {
    operationType.value = 'EDIT';
    formState.nodeNo = props.nodeNo;
    getData(props.nodeNo);
  }
}

watch(
  () => formState,
  () => {
    dirtyFlag.value = true;
  },
  {
    deep: true
  }
);

/**
 * 获取节点详情
 */
async function getData(nodeNo: string) {
  try {
    loading.value = true;
    const res = await getNodeInfo(nodeNo);

    formState.nodeNo = res.nodeNo;
    formState.transferCategory = res.transferCategory;
    if (formState.transferCategory === 'MATERIAL' || formState.transferCategory === 'ITEM') {
      // 读取选中的主产物
      sourceTransferNodeNo.value = res.transferNodeNo || '';
      sourceTransferNodeName.value = res.transferNodeName;
      hasTransferNode.value = false;
      getBomTreeInTransportReq();
    }
    formState.transferNodeName = res.transferNodeName;
    formState.transferNodeNo = res.transferNodeName || res.transferNodeNo || '';
    formState.transferMethod = res.transferMethod;
    formState.fuelType = res.fuelType;
    formState.transferRate = String(res.transferRate) as unknown as keyof typeof TransportRatioMap;
    formState.dosage = res.dosage;
    formState.unit = res.unit;
    formState.weight = res.weight;
    formState.weightUnit = res.weightUnit;
    formState.distance = res.distance;
    formState.distanceUnit = res.distanceUnit;
    formState.remark = res.remark || '';
    dirtyFlag.value = false;
    loading.value = false;
  } catch (error) {
    console.log('error', error);
    loading.value = false;
  }
}

/**
 * 保存按钮
 */
function handleConfirm() {
  console.log('handleConfirm');
  formRef.value?.validate((valid: boolean) => {
    if (valid) {
      submitFlowReq();
    }
  });
}

/**
 * 接口请求
 */
async function submitFlowReq() {
  console.log('submitFlowReq');
  try {
    loading.value = true;
    const params = {
      ...formState
    };
    if (formState.transferCategory === 'MAIN') {
      params.transferNodeName = '主产品';
    }
    if (operationType.value === 'ADD') {
      console.log('addTransportStageFlow', params);
      await addTransportStageFlow(params);
    } else {
      if (
        (formState.transferCategory === 'MATERIAL' || formState.transferCategory === 'ITEM') &&
        !hasTransferNode.value &&
        !dirtyFlag.value
      ) {
        params.transferNodeNo = sourceTransferNodeNo.value;
        params.transferNodeName = sourceTransferNodeName.value;
      }
      console.log('params', params);
      await editTransportStageFlow(params);
    }
    createMessage.success(operationType.value === 'ADD' ? '新增成功！' : '编辑成功！');
    emits('refresh', props.processNo);
    dialogVisible.value = false;
  } catch (error) {
    console.log('error', error);
    loading.value = false;
  }
}

const loadNode = async (node: Node, resolve: (data: any[]) => void) => {
  if (node.level === 0) {
    const res = await getListBomTree(props.modelNo, '-1');
    resolve(res);
  }
  if (node.level > 0) {
    const res = await getListBomTree(props.modelNo, node.data.nodeNo);
    resolve(res);
  }
};
const treeSelectProps = {
  label: 'nodeName',
  value: 'nodeNo',
  children: 'childrenList',
  isLeaf: 'isLeaf',
  disabled: (data: GetNodeInfoResult) => {
    if (data.dataType !== formState.transferCategory) {
      return true;
    }
    return false;
  }
};

const bomTreeRef = ref();
const bomTreeData = ref([]);

/**
 * 查询模型BOM树
 */
async function getBomTreeInTransportReq() {
  try {
    const res = await getBomTreeInTransport(props.modelNo);
    console.log('getBomTreeInTransportReq res', res);
    const flag = checkEmptyTree(res);
    if (flag) {
      bomTreeData.value = [];
    } else {
      bomTreeData.value = res;
    }
    if (operationType.value !== 'ADD' && !hasTransferNode.value && sourceTransferNodeName.value) {
      formState.transferNodeNo = sourceTransferNodeName.value;
    }
  } catch (error) {
    console.log('error', error);
  }
}

function checkEmptyTree(res: any[]) {
  let flag = true;
  const fn = (arr: any) => {
    if (!flag) return;
    for (let i = 0; i < arr.length; i++) {
      const item = arr[i];
      // 树里有匹配到对应的node
      if (item.nodeNo === sourceTransferNodeNo.value) {
        hasTransferNode.value = true;
      }
      if (item.dataType === formState.transferCategory) {
        flag = false;
        return;
      }
      if (item.childrenList?.length) {
        fn(item.childrenList);
      }
    }
  };

  fn(res);
  return flag;
}

/**
 * 切换运输物
 */
function handleChangeTransferCategory() {
  console.log('handleChangeTransferCategory');
  if (formState.transferCategory === 'MATERIAL' || formState.transferCategory === 'ITEM') {
    formState.transferNodeNo = '';
    formState.transferNodeName = '';
    getBomTreeInTransportReq();
  } else if (formState.transferCategory === 'MAIN') {
    const { weight, weightUnit } = transitionUnitToKg(
      props.modelDetail?.weight || '',
      props.modelDetail?.weightUnit || 't'
    );
    formState.weight = String(weight);
    formState.weightUnit = weightUnit;
  }
}

/**
 * 选择完运输的零部件/材料
 * @param nodeNo
 * @param nodeName
 */
async function handleSelectTransferNodeName(nodeNo: string, nodeName: string) {
  console.log('addTransportStageFlow--------------------------');
  formState.transferNodeNo = nodeNo;
  formState.transferNodeName = nodeName;
  console.log('addTransportStageFlow', nodeName);
  bomTreeRef.value?.blur();
  try {
    // 选择完后请求接口获取重量
    const { weight: weightRes, weightUnit: weightUnitRes } = await getNodeWeight(nodeNo);
    const { weight, weightUnit } = transitionUnitToKg(weightRes, weightUnitRes);
    formState.weight = String(weight);
    formState.weightUnit = weightUnit || '';
  } catch (error) {
    console.log('error', error);
  }
}

/**
 * 用量自动计算
 */
const dosageComputed = computed(() => {
  if (formState.weight && formState.distance) {
    return limitStrLength(
      Decimal.mul(formState.weight, formState.distance).toNumber(),
      9,
      false,
      0
    );
  } else {
    return '';
  }
});

/**
 * 用量单位自动计算
 */
const unitComputed = computed(() => {
  if (formState.weightUnit && formState.distanceUnit) {
    return `${formState.weightUnit}·${formState.distanceUnit}`;
  } else {
    return '';
  }
});
</script>

<style lang="scss">
.material-select-tree-wrapper.el-tree {
  --el-tree-node-content-height: 28px;
  --el-tree-node-hover-bg-color: #edf2f7;
  --el-tree-text-color: #435970;
  --el-text-color-placeholder: #96a7b3;

  .node-item {
    height: 24px;
  }

  .el-tree-node__content {
    margin: 0 4px;
    border-radius: 3px;
    height: 24px;

    .el-select-dropdown__item {
      padding-right: 8px;
      height: 24px;
    }

    &:has(> .is-disabled) {
      background: #fff;
    }
  }

  .material-weight-text {
    padding-right: 8px;
    font-size: 12px;
    font-family: HelveticaNeue;
    color: #7a8a99;
    line-height: 20px;
  }

  .is-disabled {
    .material-weight-text {
      color: #96a7b3;
    }
  }
}
</style>
